/*
 * MHttpConnection.java
 *
 * Created on April 16, 2008, 9:07 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package uns.fit.gis.httpconnection;

import java.io.*;
import java.util.*;
import javax.microedition.io.*;

/**
 *
 * @author pham hiep
 *
 * This class will reponsibility send request to server and receice data respond from server.
 *
 */
public class MHttpConnection implements Runnable{
    //items are list of the requests
    private Vector items;
    //worker is the thread to open http connectionn
    private Thread worker;
    //closed is the status of connection
    private boolean closed;
    //currentItem is the item quering
    private MHttpConnItem currentItem;
    
    private String cookie;
    
    private int size;
    public static final int DeltaSize=1200;
    
    /** Creates a new instance of MHttpConnection */
    public MHttpConnection() {
        this.items = new Vector();
        this.closed = false;
    }
    
    /**
     * This method used to user cancel all connection. All items in item list will be deleted.
     */
    public void abortAll(){
        System.out.println(this.items.size());
        for(int i = 0; i < items.size(); i ++){
            ((MHttpConnItem)items.elementAt(i)).setAborted(true);
            getCurrentItem().setAborted(true);
            System.out.println(i+" : "+getCurrentItem().isAborted());
        }
        this.items.removeAllElements();
    }
    
    /**
     * Add a request to the queue of requests.
     * @param _item The connection item, represents the information of connection
     */
    public void addItem(MHttpConnItem _item){
        items.addElement(_item);
    }
    
    /**
     * Set the current connection item.
     * @param currentItem The connection item  which is communicating with the server
     */
    public void setCurrentItem(MHttpConnItem currentItem) {
        this.currentItem = currentItem;
    }
    
    /**
     * Get the current connection item.
     * @return The connection item  which is communicating with the server
     */
    public MHttpConnItem getCurrentItem(){
        return this.currentItem;
    }
    
    /**
     * Get list items need to process.
     * @return The connection items  which are communicating with the server
     */
    public MHttpConnection[] getItems(){
        return null;
    }
    
    /**
     * Set list items need to process.
     * @param list of the connection items  which are communicating with the server
     */
    private void setItems(Vector _items) {
        this.items = _items;
    }
    
    /**
     * Get thread open Http connection.
     * @return thread
     */
    private Thread getWorker() {
        return worker;
    }
    
    /**
     * Set thread open Http connection.
     * @param The worker is the thread to open Http connection
     */
    private void setWorker(Thread worker) {
        this.worker = worker;
    }
    
    /**
     * Determine if the process is closed.
     * @return true if the process is closed
     */
    public boolean isClosed() {
        return closed;
    }
    
    /*
     * Get amount of data tranfered
     * @Return size of data tranfered
     */
    public int getSize() {
        return size;
    }
    
    /*
     * Set amount of data tranfered
     * @param size of data tranfered
     */
    public void setSize(int size) {
        this.size = size;
    }
    
    /**
     * Start the process.
     */
    public void start() {
        worker = new Thread(this);
        worker.start();
    }
    
    /**
     * Implements the run() method of Runnable interface.
     */
    public void run() {
        HttpConnection httpConn = null;
        DataInputStream din = null;
        while(!isClosed()) {
            
            if(!items.isEmpty()) {
                setCurrentItem((MHttpConnItem)items.firstElement());
                if(getCurrentItem().isAborted() == true){
                    items.removeElement(getCurrentItem());
                }else{
                    try {
                        httpConn = (HttpConnection)Connector.open(currentItem.getUrl());
                        httpConn.setRequestProperty("User-Agent", "mTaipanMidlet/1.0a");
                        httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                        httpConn.setRequestProperty("Accept", "text/plain,text/xml,image/*");
                        httpConn.setRequestProperty("Cookie", currentItem.getSession()); 
//                        cookie = currentItem.getSession();
//                        
//                        try{
//                        MAppController.addLog("HTTPDATA"+new String(currentItem.getData()));
//                        }catch(Exception ex){}
//                        if (cookie!=null) {
//                            httpConn.setRequestProperty("Cookie", cookie);
//                            System.out.println("HTTP CLIENT COOKIE:" + cookie);
//                            MAppController.addLog("HTTP CLIENT COOKIE: "+ cookie);
//                        } else
//                            System.out.println("HTTP CLIENT COOKIE:NULL");
                            
                        OutputStream os = null;
                        if(currentItem.isPost()) {
                            httpConn.setRequestMethod(HttpConnection.POST);
                            os = httpConn.openOutputStream();
                            
                            if(getCurrentItem().getData() != null) {
                                try {
                                    size +=getCurrentItem().getData().length;
                                    os.write(getCurrentItem().getData());
                                    //os.flush();
                                } catch(IOException ioex) {
                                    //Log the exception
                                    ioex.printStackTrace();
                                } finally {
                                    if(os != null) os.close();
                                }
                            }
                        }
                        
                        din = httpConn.openDataInputStream();
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        while(true) {
                            try {
                                baos.write(din.readByte());
                            } catch(EOFException e) {
                                break;
                            }
                        }

                        size += baos.size()+DeltaSize;
                        if(getCurrentItem().isAborted() == false){
                            getCurrentItem().getHandler().HttpLoadCompleted(
                                    baos.toByteArray(),
                                    getCurrentItem().getHandler().ERR_HTTP_COMPLETED, getCurrentItem());
                        }else{
                            System.out.println("HTTP : the connection is aborted.");
                        }
                        baos.close();
                        baos = null;
                    } catch(Exception ex) {
                        
                        if (getCurrentItem().getHandler()!=null)
                            getCurrentItem().getHandler().HttpLoadCompleted(
                                    null, getCurrentItem().getHandler().ERR_HTTP_FAIL, getCurrentItem());
                    } finally {
                        if(din != null) {
                            try {
                                din.close();
                            } catch(IOException ioex) {
                                //Log the exception
                                ioex.printStackTrace();
                            }
                        }
                        if (httpConn!=null) {
                            try {
                                httpConn.close();
                            } catch(IOException e) {
                            }
                        }
                    }
                    items.removeElement(getCurrentItem());
                }
            } else
                try {
                    Thread.sleep(100);
                } catch(InterruptedException e) {
                }
        }
    }
    
    /**
     * QueryItem used to open connection in the process test or debug.
     */
    public void queryItem(MHttpConnItem item){
        HttpConnection httpConn = null;
        DataInputStream din = null;
        
        if(item != null && item.isAborted()==false) {
            try {
                httpConn = (HttpConnection)Connector.open(item.getUrl());
                httpConn.setRequestProperty("User-Agent", "mTaipanMidlet/1.0a");
                httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                httpConn.setRequestProperty("Accept", "text/plain,text/xml,image/*");
                if (item.getSession().length()!=0 && item.isUseSession())
                    httpConn.setRequestProperty("Cookie", "PHPSESSID=" + item.getSession());
                
                OutputStream os = null;
                if(item.isPost()) {
                    httpConn.setRequestMethod(HttpConnection.POST);
                    os = httpConn.openOutputStream();
                    
                    if(item.getData() != null) {
                        try {
                            setSize(getSize() + item.getData().length);
                            os.write(item.getData());
                            //os.flush();
                        } catch(IOException ioex) {
                            //Log the exception
                            ioex.printStackTrace();
                        } finally {
                            if(os != null) os.close();
                        }
                    }
                }
                
                din = httpConn.openDataInputStream();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                while(true) {
                    try {
                        baos.write(din.readByte());
                    } catch(EOFException e) {
                        break;
                    }
                }
                
                
                System.out.println("URL:  "+item.getUrl()+" " +
                        "||| Length:"+baos.toString().length());
                
                setSize(getSize() + (baos.size()+DeltaSize));
                item.getHandler().HttpLoadCompleted(
                        baos.toByteArray(),
                        13, item);
                baos.close();
                baos = null;
            } catch(Exception ex) {
                //Log the exception
                ex.printStackTrace();
                
                if (item.getHandler()!=null)
                    item.getHandler().HttpLoadCompleted(null, item.getHandler().ERR_HTTP_FAIL, item);
            } finally {
                if(din != null) {
                    try {
                        din.close();
                    } catch(IOException ioex) {
                        //Log the exception
                        ioex.printStackTrace();
                    }
                }
                if (httpConn!=null) {
                    try {
                        httpConn.close();
                    } catch(IOException e) {
                    }
                }
            }
        } else
            try {
                Thread.sleep(100);
            } catch(InterruptedException e) {
            }
    }
}


